#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "db.h"
#include "xmalloc.h"

const char db_err_init_s[] = "DB init (%s) failed with %d";
const char db_err_create_s[] = "DB create table %s failed with %d";
const char db_err_close_s[] = "DB close handle failed with %d";
static char db_arg[DB_ARGLEN + 1];


int
db_set_arg(const char *__arg)
{
  assert(__arg != NULL);
  memset(db_arg, 0, DB_ARGLEN+1);
  if (__arg)
  {
    strncpy(db_arg, __arg, DB_ARGLEN);
#ifdef db_parse_arg
    return ( db_parse_arg(db_arg) );
#else
    return (0);
#endif
  }

  return (1);
}

char *
db_get_arg(void)
{
  return ((char *)db_arg);
}

db_result_t *
db_create_result(void)
{
  db_result_t *rs = ncmalloc(1, sizeof(db_result_t));

  rs->data = NULL;
  rs->len = 0;
  rs->nextrow = NULL;
  rs->nextcol = NULL;
  return (rs);
}

void
db_free_results(db_result_t *first_elem)
{
  db_result_t *tmp = NULL, *row_vect = NULL, *col_vect = NULL;

  if (!first_elem) return;
  row_vect = first_elem;
  do {
    col_vect = row_vect;
    row_vect = row_vect->nextrow;

    do {
      tmp = col_vect;
      if (col_vect) col_vect = col_vect->nextcol;
      if (tmp->data) {
        free((void *)tmp->data);
      }
      ncfree(tmp, sizeof(db_result_t));
    } while (col_vect);
  } while (row_vect);
}

db_stmt_t *
db_init_stmt(const db_datatype_t dtypes[], int len)
{
  int idx;

  db_stmt_t *st = ncmalloc(len+1, sizeof(db_stmt_t));
  for (idx = 0; idx < len; idx++) {
    st[idx].dtype = dtypes[idx];
  }
  st[idx].dtype = db_nulltype;
  return (st);
}

__inline__ void
db_bind_val(db_stmt_t *st, int *idx, const void *data, int len)
{
  if (st[*idx].dtype == db_nulltype) return;
  st[*idx].bind_value = data;
  st[*idx].len = len;
  (*idx)++;
}

__inline__ void
db_bind_str(db_stmt_t *st, int *idx, const char *str, int len)
{
  db_bind_val(st, idx, (const void *) str, sizeof(char)*len);
}

__inline__ void
db_bind_int(db_stmt_t *st, int *idx, const long int *num)
{
  db_bind_val(st, idx, (const void *) num, sizeof(long int));
}

__inline__ void
db_bind_chr(db_stmt_t *st, int *idx, const char *c)
{
  db_bind_val(st, idx, (const void *) c, sizeof(char));
}

void
db_free_stmt(void *__db_st, db_stmt_t *st, int len)
{
  if (__db_st) {
    db_finish_stmt(__db_st);
  }
  ncfree(st, (len+1)*(sizeof(db_stmt_t)));
}

